/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


// nsIController
function TreeController(treeView)
{
    this.treeView = treeView;
}

TreeController.prototype =
{
    commands: "copy cut paste selectAll".split(" "),
    
    get commandSet()
    {
        var prototype = TreeController.prototype;
        var commandSet = new Set(prototype.commands);
        return lazyInit(prototype, "commandSet", commandSet);
    },
    
    isCommandEnabled: function(command)
    {
        var treeView = this.treeView;
        var selection = treeView.selection;
        
        switch (command)
        {
            case "cmd_copy":
                return (selection.count > 0);
                
            case "cmd_cut":
                return (selection.count > 0);
                
            case "cmd_paste":
                return (this._getClipboardEntries().length > 0);
                
            case "cmd_selectAll":
                return true;
                
            default:
                throw new Error("invalid command: " + command);
        }
    },
    
    supportsCommand: function(command)
    {
        // strip "cmd_"
        command = command.substr(4);
        return (command in this.commandSet);
    },
    
    doCommand: function(command)
    {
        if (this.isCommandEnabled(command))        
            this[command]();
    },
    
    onEvent: function(eventName) { /* empty */ },
    
    cmd_copy: function()
    {
        var treeView = this.treeView;
        var entries = treeView.selectedEntries;
        var transferable = this._createTransferable(entries);
        clipboard.setData(transferable, null, Ci.nsIClipboard.kGlobalClipboard);
    },
    
    cmd_cut: function()
    {
        var treeView = this.treeView;
        this.cmd_copy();
        treeView.removeEntries(treeView.selectedIndexes);
    },
    
    cmd_paste: function()
    {
        var treeView = this.treeView;
        var index = treeView.selection.currentIndex;
        var entries = this._getClipboardEntries();
        treeView.addEntries(index, entries, false);
    },
    
    cmd_selectAll: function()
    {
        var treeView = this.treeView;
        treeView.selection.selectAll();
    },
    
    _getClipboardEntries: function()
    {
        var transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
        transferable.addDataFlavor(FLAVOR_SAVEFILETO_ENTRIES);
        transferable.addDataFlavor("text/unicode");
        
        clipboard.getData(transferable, Ci.nsIClipboard.kGlobalClipboard);
        var flavor = {}, data = {}, length = {};
        
        try       { transferable.getAnyTransferData(flavor, data, length); }
        catch (e) { return []; }
        
        var entries = [];
        var file, path;
        
        switch (flavor.value)
        {
            case FLAVOR_SAVEFILETO_ENTRIES:
                var json = data.value.QueryInterface(Ci.nsISupportsString).data;
                entries = JSON.parse(json);
                break;
                
            case "text/unicode":
                path = data.value.QueryInterface(Ci.nsISupportsString).data;
                break;
                
            default:
                throw new Error("invalid flavor: " + flavor.value);
        }
        
        if (path)
        {
            try
            {
                var f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
                f.initWithPath(path);
                file = f;
            }
            catch (e) { /* ignore */ }
        }
        
        if (file && file.exists() && file.isDirectory())
            entries = [{type: "folder", label: file.leafName, path: file.path, menu: true}];
        
        return entries;
    },
    
    _createTransferable: function(entries)
    {
        var transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
        
        function addData(flavor, value)
        {
            var str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
            str.data = value;
            transferable.addDataFlavor(flavor);
            transferable.setTransferData(flavor, str, value.length * 2);
        }
        
        var json = JSON.stringify(entries);
        addData(FLAVOR_SAVEFILETO_ENTRIES, json);
        
        var isFolder = function(entry) { return (entry.type == "folder"); }
        if (entries.every(isFolder))
            addData("text/unicode", [entry.path for each (entry in entries)].join("\n"));
        
        return transferable;
    }
}
